/*
 * @Copyright: 2016 www.yyfax.com Inc. All rights reserved.
 */
package com.yyfax.pay.order.controller;

import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import com.yyfax.framework.exception.YYException;
import com.yyfax.framework.yyfax.enums.RspCodeEnum;
import com.yyfax.pay.common.constants.PayConstants;
import com.yyfax.pay.common.enums.PayRspCodeEnum;
import com.yyfax.pay.common.exception.YYPayException;
import com.yyfax.pay.common.exception.YYPayOrderException;
import com.yyfax.pay.order.data.service.PayOrderService;
import com.yyfax.pay.order.model.po.PayOrderPO;

/**
 * Web异常统一处理
 * 
 * @author jiangmy
 * @date 2016-08-15 14:33:03
 * @since v1.0.0
 */
@ControllerAdvice("com.yyfax.pay.order.controller.web")
public class WebExceptionHandler {
	protected Logger logger = LoggerFactory.getLogger(getClass());

	@Resource
	private PayConstants payconstants;
	
	@Autowired
	private PayOrderService payOrderService;

	@ExceptionHandler({ ServletException.class })
	public String http404(HttpServletRequest request, ServletException e) throws IOException {
		logger.error("HttpRequest error:{}", request.getRequestURL());
		logger.error("HttpRequest error stack :", e);
		return "error/404";
	}

	@ExceptionHandler(RuntimeException.class)
	public String handleBizException(HttpServletRequest request, RuntimeException e) throws IOException {
		logger.error("runtime error occurs during :{}", request.getRequestURI());
		logger.error("runtime error stack :", e);
		return "error/404";
	}

	/**
	 * 订单异常处理
	 * 
	 * @author buyi
	 * @date 2017-05-06 15:04:14
	 * @since v1.0.0
	 * @param request
	 * @param e
	 * @return
	 * @throws IOException
	 */
	@ExceptionHandler({ YYPayOrderException.class })
	public String handleYYPayOderException(HttpServletRequest request, YYPayOrderException e) throws IOException {
		logger.error("Unknown error occurs during :{} - {}", request.getMethod(), request.getRequestURI());
		logger.error("Unknown system error stack:", e);
		String backUrl = null;
		if (StringUtils.isNotBlank(e.getTradeOrderId()) && StringUtils.isNotBlank(e.getMerchantCode())) {// 如果存在支付订单号
			try {
				// 默认值支付订单，如果业务扩展再做判断
				PayOrderPO payOrderPO = payOrderService.queryByPayOrderId(e.getMerchantCode(), e.getTradeOrderId());

				// 支付默认回调地址为物品地址
				if (payOrderPO != null && StringUtils.isNotBlank(payOrderPO.getGoodsUrl())) {
					backUrl = payOrderPO.getGoodsUrl();
				}
			} catch (Exception e1) {
				logger.error("异常统一处理，查询订单信息异常", e1);
			}
		}

		return handle(request, e.getCode(), e.getDisplay(), backUrl);
	}

	@ExceptionHandler({ YYPayException.class })
	public String handleYYPayException(HttpServletRequest request, YYPayException e) throws IOException {
		logger.error("Unknown error occurs during :{} - {}", request.getMethod(), request.getRequestURI());
		logger.error("Unknown system error stack:", e);

		return handle(request, e.getCode(), e.getDisplay(), null);
	}

	@ExceptionHandler({ YYException.class })
	public String handleYYException(HttpServletRequest request, YYException e) throws IOException {
		logger.error("Unknown error occurs during :{} - {}", request.getMethod(), request.getRequestURI());
		logger.error("Unknown system error stack:", e);

		return handle(request, e.getCode(), e.getDisplay(), null);
	}

	@ExceptionHandler({ Error.class, Exception.class, Throwable.class })
	public String exception(HttpServletRequest request, Throwable e) throws IOException {
		logger.error("Unknown error occurs during :{}", request.getRequestURI());
		logger.error("Unknown system error stack:", e);
		// request.setAttribute("exception", e);
		// return "error/500";
		// return "error/error";

		return handle(request, null, null, null);
	}

	public String handle(HttpServletRequest request, Integer code, String display, String backUrl) {
		RspCodeEnum rspCodeEnum = null;
		if (code != null) {
			rspCodeEnum = PayRspCodeEnum.fromValue(code);
		}

		if (rspCodeEnum == null) {
			// 如果没有响应码，则默认为网络异常
			rspCodeEnum = PayRspCodeEnum.COMMON_ERR0R_NET_ERROR;
		}

		if (StringUtils.isBlank(display)) {
			display = rspCodeEnum.getDisplay();
		}

		request.setAttribute("code", rspCodeEnum.getValue());
		request.setAttribute("display", display);
		request.setAttribute("backUrl", backUrl);
		
		request.setAttribute(payconstants.getCtx(), request.getContextPath());

		return "error/error";
	}

}
